/*
 * 项   目：code-generator
 * 作   者：LuoYiMin
 * 邮   箱：1725990142@qq.com
 * 创建时间：2018/12/27 15:17
 */
package com.roin.util.code.generator.controller;

import com.roin.util.code.generator.model.HtmlConfig;
import com.roin.util.code.generator.model.HtmlConfigColumn;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.control.cell.ComboBoxTableCell;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.util.Callback;
import javafx.util.converter.DefaultStringConverter;

import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;

public class HtmlConfigController extends BaseController {

    @FXML
    private TextField baseUrlTextField;
    @FXML
    private CheckBox showCheckBox;
    @FXML
    private CheckBox rowToolCheckBox;
    @FXML
    private CheckBox addCheckBox;
    @FXML
    private CheckBox updateCheckBox;
    @FXML
    private CheckBox deleteCheckBox;
    @FXML
    private CheckBox batchDeleteCheckBox;
    @FXML
    private TableView<HtmlConfigColumn> tableView;
    @FXML
    private TableColumn fieldColumn;
    @FXML
    private TableColumn titleColumn;
    @FXML
    private TableColumn widthColumn;
    @FXML
    private TableColumn alignColumn;
    @FXML
    private TableColumn sortColumn;
    @FXML
    private TableColumn fixedColumn;
    @FXML
    private TableColumn hideColumn;
    @FXML
    private TableColumn templetColumn;
    @FXML
    private TableColumn filterColumn;
    @FXML
    private TableColumn filterTypeColumn;

    @FXML
    private TableView<HtmlConfigColumn> formTableView;
    @FXML
    private TableColumn fieldColumn1;
    @FXML
    private TableColumn needInsertColumn;
    @FXML
    private TableColumn inputTypeColumn;
    @FXML
    private TableColumn requiredColumn;
    @FXML
    private TableColumn hideInAddFormColumn;
    @FXML
    private TableColumn editableColumn;
    @FXML
    private TableColumn maxLengthColumn;
    @FXML
    private TableColumn placeholderColumn;
    @FXML
    private TableColumn submitColumn;
    @FXML
    private TableColumn dateTypeColumn;
    @FXML
    private TableColumn rangeColumn;
    @FXML
    private TableColumn formatColumn;
    @FXML
    private TableColumn defaultDateColumn;
    @FXML
    private TableColumn minDateColumn;
    @FXML
    private TableColumn maxDateColumn;
    @FXML
    private TableColumn handlerColumn;

    private HtmlConfig config;
    private List<HtmlConfigColumn> columns;




    @FXML
    public void addNewColumn(){
        columns.add(new HtmlConfigColumn());
        tableView.refresh();
        formTableView.refresh();
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        tableView.setEditable(true);
        formTableView.setEditable(true);

        addCheckBox.selectedProperty().addListener(new ChangeListener<Boolean>() {
            @Override
            public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
                    formTableView.setEditable(newValue || updateCheckBox.isSelected());
            }
        });
        updateCheckBox.selectedProperty().addListener(new ChangeListener<Boolean>() {
            @Override
            public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
                    formTableView.setEditable(newValue || addCheckBox.isSelected());
            }
        });

        Callback callback = TextFieldTableCell.<HtmlConfigColumn>forTableColumn();
        fieldColumn.setCellValueFactory(new PropertyValueFactory<>("field"));
        fieldColumn.setCellFactory(callback);
        fieldColumn.setOnEditCommit((EventHandler<CellEditEvent<HtmlConfigColumn, String>>) event -> event.getTableView().getItems().get(event.getTablePosition().getRow()).setField(event.getNewValue()));
        titleColumn.setCellValueFactory(new PropertyValueFactory<>("title"));
        titleColumn.setCellFactory(callback);
        titleColumn.setOnEditCommit((EventHandler<CellEditEvent<HtmlConfigColumn, String>>) event -> event.getTableView().getItems().get(event.getTablePosition().getRow()).setTitle(event.getNewValue()));
        widthColumn.setCellValueFactory(new PropertyValueFactory<>("width"));
        widthColumn.setCellFactory(callback);
        widthColumn.setOnEditCommit((EventHandler<CellEditEvent<HtmlConfigColumn, String>>) event -> event.getTableView().getItems().get(event.getTablePosition().getRow()).setWidth(event.getNewValue()));
        alignColumn.setCellValueFactory(new PropertyValueFactory<>("align"));
        ObservableList< String> alignValues = FXCollections.observableArrayList("left","center","right");
        alignColumn.setCellFactory(ComboBoxTableCell.forTableColumn(new DefaultStringConverter(),alignValues));
        alignColumn.setOnEditCommit((EventHandler<CellEditEvent<HtmlConfigColumn, String>>) event -> event.getTableView().getItems().get(event.getTablePosition().getRow()).setAlign(event.getNewValue()));
        sortColumn.setCellValueFactory(new PropertyValueFactory<HtmlConfigColumn, Boolean>("sort"));
        sortColumn.setCellFactory(CheckBoxTableCell.forTableColumn(index -> {
            HtmlConfigColumn g = columns.get(index);
            ObservableValue<Boolean> retval = new SimpleBooleanProperty(g, "sort", g.isSort());
            retval.addListener((observable, oldValue, newValue) -> g.setSort(newValue));
            return retval;
        }));
        fixedColumn.setCellValueFactory(new PropertyValueFactory<HtmlConfigColumn, Boolean>("fixed"));
        fixedColumn.setCellFactory(CheckBoxTableCell.forTableColumn(index -> {
            HtmlConfigColumn g = columns.get(index);
            ObservableValue<Boolean> retval = new SimpleBooleanProperty(g, "fixed", g.isFixed());
            retval.addListener((observable, oldValue, newValue) -> g.setFixed(newValue));
            return retval;
        }));
        hideColumn.setCellValueFactory(new PropertyValueFactory<HtmlConfigColumn, Boolean>("hide"));
        hideColumn.setCellFactory(CheckBoxTableCell.forTableColumn(index -> {
            HtmlConfigColumn g = columns.get(index);
            ObservableValue<Boolean> retval = new SimpleBooleanProperty(g, "hide", g.isHide());
            retval.addListener((observable, oldValue, newValue) -> g.setHide(newValue));
            return retval;
        }));
        templetColumn.setCellValueFactory(new PropertyValueFactory<HtmlConfigColumn, Boolean>("templet"));
        templetColumn.setCellFactory(CheckBoxTableCell.forTableColumn(index -> {
            HtmlConfigColumn g = columns.get(index);
            ObservableValue<Boolean> retval = new SimpleBooleanProperty(g, "templet", g.isTemplet());
            retval.addListener((observable, oldValue, newValue) -> g.setTemplet(newValue));
            return retval;
        }));
        filterColumn.setCellValueFactory(new PropertyValueFactory<HtmlConfigColumn, Boolean>("filter"));
        filterColumn.setCellFactory(CheckBoxTableCell.forTableColumn(index -> {
            HtmlConfigColumn g = columns.get(index);
            ObservableValue<Boolean> retval = new SimpleBooleanProperty(g, "filterColumn", g.isFilterColumn());
            retval.addListener((observable, oldValue, newValue) -> g.setFilterColumn(newValue));
            return retval;
        }));
        filterTypeColumn.setCellValueFactory(new PropertyValueFactory<>("filterType"));
        ObservableList< String> filterTypeValues = FXCollections.observableArrayList("text","select","date","date-range");
        filterTypeColumn.setCellFactory(ComboBoxTableCell.forTableColumn(new DefaultStringConverter(),filterTypeValues));
        filterTypeColumn.setOnEditCommit((EventHandler<CellEditEvent<HtmlConfigColumn, String>>) event -> event.getTableView().getItems().get(event.getTablePosition().getRow()).setFilterType(event.getNewValue()));

        handlerColumn.setCellFactory((col)->{
            return new TableCell<HtmlConfigColumn,Integer>(){
                @Override
                protected void updateItem(Integer item, boolean empty) {
                    super.updateItem(item, empty);
                    this.setGraphic(null);
                    this.setText(null);
                    if (!empty){
                        Button button = new Button("删除");
                        button.setOnMouseClicked((me)->{
                            this.getTableView().getItems().remove(this.getIndex());
                            formTableView.refresh();
                        });
                        this.setGraphic(button);
                    }
                }
            };
        });

        //-------------------------------

        fieldColumn1.setCellValueFactory(new PropertyValueFactory<>("field"));
        fieldColumn1.setCellFactory(callback);
        inputTypeColumn.setCellValueFactory(new PropertyValueFactory<>("inputType"));
        ObservableList< String> inputTypeValues = FXCollections.observableArrayList("text","select","radio","checkbox","switch","date");
        inputTypeColumn.setCellFactory(ComboBoxTableCell.forTableColumn(new DefaultStringConverter(),inputTypeValues));
        inputTypeColumn.setOnEditCommit((EventHandler<CellEditEvent<HtmlConfigColumn, String>>) event -> event.getTableView().getItems().get(event.getTablePosition().getRow()).setInputType(event.getNewValue()));
        maxLengthColumn.setCellValueFactory(new PropertyValueFactory<>("maxLength"));
        maxLengthColumn.setCellFactory(callback);
        maxLengthColumn.setOnEditCommit((EventHandler<CellEditEvent<HtmlConfigColumn, String>>) event -> event.getTableView().getItems().get(event.getTablePosition().getRow()).setMaxLength(event.getNewValue()));
        placeholderColumn.setCellValueFactory(new PropertyValueFactory<>("placeholder"));
        placeholderColumn.setCellFactory(callback);
        placeholderColumn.setOnEditCommit((EventHandler<CellEditEvent<HtmlConfigColumn, String>>) event -> event.getTableView().getItems().get(event.getTablePosition().getRow()).setPlaceholder(event.getNewValue()));
        needInsertColumn.setCellValueFactory(new PropertyValueFactory<HtmlConfigColumn, Boolean>("needInsert"));
        needInsertColumn.setCellFactory(CheckBoxTableCell.forTableColumn(index -> {
            HtmlConfigColumn g = columns.get(index);
            ObservableValue<Boolean> retval = new SimpleBooleanProperty(g, "needInsert", g.isNeedInsert());
            retval.addListener((observable, oldValue, newValue) -> g.setNeedInsert(newValue));
            return retval;
        }));
        requiredColumn.setCellValueFactory(new PropertyValueFactory<HtmlConfigColumn, Boolean>("required"));
        requiredColumn.setCellFactory(CheckBoxTableCell.forTableColumn(index -> {
            HtmlConfigColumn g = columns.get(index);
            ObservableValue<Boolean> retval = new SimpleBooleanProperty(g, "required", g.isRequired());
            retval.addListener((observable, oldValue, newValue) -> g.setRequired(newValue));
            return retval;
        }));
        hideInAddFormColumn.setCellValueFactory(new PropertyValueFactory<HtmlConfigColumn, Boolean>("hideInAddForm"));
        hideInAddFormColumn.setCellFactory(CheckBoxTableCell.forTableColumn(index -> {
            HtmlConfigColumn g = columns.get(index);
            ObservableValue<Boolean> retval = new SimpleBooleanProperty(g, "hideInAddForm", g.isHideInAddForm());
            retval.addListener((observable, oldValue, newValue) -> g.setHideInAddForm(newValue));
            return retval;
        }));
        editableColumn.setCellValueFactory(new PropertyValueFactory<HtmlConfigColumn, Boolean>("editable"));
        editableColumn.setCellFactory(CheckBoxTableCell.forTableColumn(index -> {
            HtmlConfigColumn g = columns.get(index);
            ObservableValue<Boolean> retval = new SimpleBooleanProperty(g, "editable", g.isEditable());
            retval.addListener((observable, oldValue, newValue) -> g.setEditable(newValue));
            return retval;
        }));
        submitColumn.setCellValueFactory(new PropertyValueFactory<HtmlConfigColumn, Boolean>("submit"));
        submitColumn.setCellFactory(CheckBoxTableCell.forTableColumn(index -> {
            HtmlConfigColumn g = columns.get(index);
            ObservableValue<Boolean> retval = new SimpleBooleanProperty(g, "submit", g.isSubmit());
            retval.addListener((observable, oldValue, newValue) -> g.setSubmit(newValue));
            return retval;
        }));
        dateTypeColumn.setCellValueFactory(new PropertyValueFactory<>("dateType"));
        ObservableList< String> dateTypeValues = FXCollections.observableArrayList("year","month","date","datetime","time");
        dateTypeColumn.setCellFactory(ComboBoxTableCell.forTableColumn(new DefaultStringConverter(),dateTypeValues));
        dateTypeColumn.setOnEditCommit((EventHandler<CellEditEvent<HtmlConfigColumn, String>>) event -> event.getTableView().getItems().get(event.getTablePosition().getRow()).setDateType(event.getNewValue()));
        rangeColumn.setCellValueFactory(new PropertyValueFactory<HtmlConfigColumn, Boolean>("range"));
        rangeColumn.setCellFactory(CheckBoxTableCell.forTableColumn(index -> {
            HtmlConfigColumn g = columns.get(index);
            ObservableValue<Boolean> retval = new SimpleBooleanProperty(g, "range", g.isRange());
            retval.addListener((observable, oldValue, newValue) -> g.setRange(newValue));
            return retval;
        }));
        formatColumn.setCellValueFactory(new PropertyValueFactory<>("format"));
        formatColumn.setCellFactory(callback);
        formatColumn.setOnEditCommit((EventHandler<CellEditEvent<HtmlConfigColumn, String>>) event -> event.getTableView().getItems().get(event.getTablePosition().getRow()).setFormat(event.getNewValue()));
        defaultDateColumn.setCellValueFactory(new PropertyValueFactory<>("defaultDate"));
        defaultDateColumn.setCellFactory(callback);
        defaultDateColumn.setOnEditCommit((EventHandler<CellEditEvent<HtmlConfigColumn, String>>) event -> event.getTableView().getItems().get(event.getTablePosition().getRow()).setDefaultDate(event.getNewValue()));
        minDateColumn.setCellValueFactory(new PropertyValueFactory<>("minDate"));
        minDateColumn.setCellFactory(callback);
        minDateColumn.setOnEditCommit((EventHandler<CellEditEvent<HtmlConfigColumn, String>>) event -> event.getTableView().getItems().get(event.getTablePosition().getRow()).setMinDate(event.getNewValue()));
        maxDateColumn.setCellValueFactory(new PropertyValueFactory<>("maxDate"));
        minDateColumn.setCellFactory(callback);
        maxDateColumn.setOnEditCommit((EventHandler<CellEditEvent<HtmlConfigColumn, String>>) event -> event.getTableView().getItems().get(event.getTablePosition().getRow()).setMaxDate(event.getNewValue()));
    }


    public void setConfig(HtmlConfig config) {
        this.config = config;
        renderUI(config);
        if(getDialogStage().getOnCloseRequest()==null){
            //窗口关闭时，重置新值
            getDialogStage().setOnCloseRequest(event -> {
                this.config.setBaseUrl(baseUrlTextField.getText());
                this.config.setShowCheckBox(showCheckBox.isSelected());
                this.config.setRowTool(rowToolCheckBox.isSelected());
                this.config.setNeedAddForm(addCheckBox.isSelected());
                this.config.setNeedEditForm(updateCheckBox.isSelected());
                this.config.setCanDelete(deleteCheckBox.isSelected());
                this.config.setCanBatchDelete(batchDeleteCheckBox.isSelected());
            });
        }

    }

    private void renderUI(HtmlConfig htmlConfig) {
        baseUrlTextField.setText(htmlConfig.getBaseUrl());
        showCheckBox.setSelected(htmlConfig.isShowCheckBox());
        rowToolCheckBox.setSelected(htmlConfig.isRowTool());
        addCheckBox.setSelected(htmlConfig.isNeedAddForm());
        updateCheckBox.setSelected(htmlConfig.isNeedEditForm());
        deleteCheckBox.setSelected(htmlConfig.isCanDelete());
        batchDeleteCheckBox.setSelected(htmlConfig.isCanBatchDelete());
        this.columns = htmlConfig.getColumns();
        tableView.setItems(FXCollections.observableList(columns));
        formTableView.setItems(FXCollections.observableList(columns));
        if (!htmlConfig.isNeedEditForm() && !htmlConfig.isNeedAddForm()){
            formTableView.setEditable(false);
        }
    }
}
